package com.example.demo.service;

import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import org.activiti.api.model.shared.model.VariableInstance;
import org.activiti.api.process.model.ProcessDefinition;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.GetProcessInstancesPayloadBuilder;
import org.activiti.api.process.model.builders.GetVariablesPayloadBuilder;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.model.payloads.GetProcessInstancesPayload;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.*;
import org.activiti.api.task.model.payloads.GetTaskVariablesPayload;
import org.activiti.api.task.model.payloads.GetTasksPayload;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.bpmn.model.*;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstanceBuilder;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ProcessService {
    @Autowired
    private ProcessRuntime processRuntime;
    @Autowired
    private TaskRuntime taskRuntime;
    @Autowired
    private ProcessEngine processEngine;
    public Map<String,Object> init(){
        Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
        Map<String,Object> map=new HashMap<>();
        map.put("可用的定义流程总数",processDefinitionPage.getTotalItems());
        for (ProcessDefinition definition : processDefinitionPage.getContent()) {
            map.put("流程内容",((ProcessDefinition)map.get("流程内容")).toString()+"|"+definition.toString());
        }
        return map;
    }



    public String createInstance(String username){
        ProcessInstance instance = processRuntime.start(ProcessPayloadBuilder.start().withProcessDefinitionKey("applyProcess").withVariable("user",username).build());
        System.out.println("创建实例用户名:"+username);
        return instance.getId();
    }

    public Map<String,Object> apply(String username) {
        Page<Task> page = taskRuntime.tasks(Pageable.of(0, 10));
        Map<String,Object> map=new HashMap<>();
        if (page.getTotalItems()<=0){
            System.out.println("没有任务");
            map.put("result","申请失败,请您先创建实例!");
            return map;
        }
        for (Task task : page.getContent()) {
            String processInstanceId = task.getProcessInstanceId();
            System.out.println("任务实例Id"+processInstanceId);
            List<VariableInstance> variables = processRuntime.variables(new GetVariablesPayloadBuilder().withProcessInstanceId(processInstanceId).build());
            System.out.println("参数集合大小:"+variables.size());
            boolean isHaveTask=false;
            int taskNum=0;
            for (VariableInstance variable : variables) {
                System.out.println(variable.getName()+":"+((String)variable.getValue()));
                if (variable.getName().equals("user")){
                    System.out.println("找到了user变量");
                    if (((String)variable.getValue()).equals(username)){
                        taskNum++;
                        isHaveTask=true;
                        //身份符合,拾取任务
                        taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());
                        //完成任务
                        taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());
                        break;
                    }
                }
            }
            if (!isHaveTask){
                System.out.println("有任务,但不符合条件");
                map.put("result","申请失败,请您先创建实例!");
                return map;
            }
            map.put("result","提交申请成功!");
            map.put("count",taskNum);
            return map;
        }
        return map;

    }

    public List<HistoricProcessInstance> queryUserInstance(String usernameFromToken) {
//        List<org.activiti.engine.task.Task> list = processEngine.getTaskService().createTaskQuery().taskCandidateOrAssigned(usernameFromToken).list();
        System.out.println("查询param-负责人:"+usernameFromToken);
//        Page<ProcessInstance> processInstancePage = processRuntime.processInstances(Pageable.of(0, 10));

        List<HistoricProcessInstance> list = processEngine.getHistoryService().createHistoricProcessInstanceQuery().startedBy(usernameFromToken).orderByProcessInstanceStartTime().desc().list();
//        Map<String,Object> map=new HashMap<>();
//        List<Map<String,Object>> list2=new ArrayList<>();
//        if (processInstancePage.getTotalItems()<=0){
//            System.out.println("没有任务");
//            return list2;
//        }
//        for (ProcessInstance processInstance : processInstancePage.getContent()) {
//            map.put("instanceId",processInstance.getId());
//            map.put("name",processInstance.getName());
//            map.put("status",processInstance.getStatus());
//            map.put("dk",processInstance.getProcessDefinitionKey());
//            map.put("did",processInstance.getProcessDefinitionId());
//            map.put("startDate",processInstance.getStartDate());
//            map.put("initiator",processInstance.getInitiator());
//            list2.add(map);
//        }
        return list;

    }

    public String userAddTask(String usernameFromToken,Map<String,Object> map) {
        String instanceId = this.createInstance(usernameFromToken);
        map.put("user",usernameFromToken);
        System.out.println("实例Id:"+instanceId);
        //?
        Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 10));
        if (tasks.getTotalItems()<=0){
            return "失败,没有实例";
        }else{
            for (Task task : tasks.getContent()) {
                List<VariableInstance> variables = processRuntime.variables(new GetVariablesPayloadBuilder().withProcessInstanceId(instanceId).build());
                for (VariableInstance variable : variables) {
                    if (variable.getName().equals("user")){
                        System.out.println("变量值:"+variable.getValue());
                        System.out.println("用户名:"+usernameFromToken);
                    }
                    if (variable.getName().equals("user")&&variable.getValue().equals(usernameFromToken)){
                        System.out.println("当前任务负责人:"+task.getAssignee());
//                        System.out.println("检测到实例,拾取任务");
                     taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());
                        System.out.println("完成任务");
                        taskRuntime.setVariables(new SetTaskVariablesPayloadBuilder().withTaskId(task.getId()).withVariables(map).build());
                        taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());
                        return "提交成功";
                    }
                }
            }
            return "提交失败";
        }


    }
    public String hrTask(String usernameFromToken, String taskId,String isAgree) {
        Page<Task> page = taskRuntime.tasks(Pageable.of(0, 10), new GetTasksPayloadBuilder().withGroup("hr").build());
        if (page.getTotalItems()<=0){
            return "无需要审批的任务";
        }
        for (Task task : page.getContent()) {
            if (task.getId().equals(taskId)){
                //拾取任务
                taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(taskId).build());
                if (isAgree.equals("yes")){

//                    taskRuntime.release(new ReleaseTaskPayloadBuilder().withTaskId(taskId).build());
                    //完成任务
                    taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskId).withVariable("isAgree",isAgree).build());
                    return "审批成功";
                }else{
                    //驳回操作

                    //获取任务
                    String processInstanceId = task.getProcessInstanceId();

                    HistoryService historyService = processEngine.getHistoryService();
                    RepositoryService repositoryService = processEngine.getRepositoryService();
                    RuntimeService runtimeService = processEngine.getRuntimeService();
                    TaskService taskService = processEngine.getTaskService();
                    // 取得所有历史任务按时间降序排序
                    List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
                            .processInstanceId(processInstanceId)
                            .orderByTaskCreateTime()
                            .desc()
                            .list();
                    if (ObjectUtils.isEmpty(htiList) || htiList.size() < 2) {
                        return "驳回失败,";
                    }
                    // list里的第二条代表上一个任务
                    HistoricTaskInstance lastTask = htiList.get(1);
                    // list里第二条代表当前任务
                    HistoricTaskInstance curTask = htiList.get(0);
                    // 当前节点的executionId
                    String curExecutionId = curTask.getExecutionId();
                    // 上个节点的taskId
                    String lastTaskId = lastTask.getId();
                    // 上个节点的executionId
                    String lastExecutionId = lastTask.getExecutionId();
                    if (null == lastTaskId) {
                        throw new RuntimeException("LAST TASK IS NULL");
                    }
                    String processDefinitionId = lastTask.getProcessDefinitionId();
                    BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
                    String lastActivityId = null;
                    List<HistoricActivityInstance> haiFinishedList = historyService.createHistoricActivityInstanceQuery()
                            .executionId(lastExecutionId).finished().list();
                    for (HistoricActivityInstance hai : haiFinishedList) {
                        if (lastTaskId.equals(hai.getTaskId())) {
                            // 得到ActivityId，只有HistoricActivityInstance对象里才有此方法
                            lastActivityId = hai.getActivityId();
                            break;
                        }
                    }
                    // 得到上个节点的信息
                    FlowNode lastFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(lastActivityId);
                    // 取得当前节点的信息
                    Execution execution = runtimeService.createExecutionQuery().executionId(curExecutionId).singleResult();
                    String curActivityId = execution.getActivityId();
                    FlowNode curFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(curActivityId);
                    //记录当前节点的原活动方向
                    List<SequenceFlow> oriSequenceFlows = new ArrayList<>();
                    oriSequenceFlows.addAll(curFlowNode.getOutgoingFlows());
                    //清理活动方向
                    curFlowNode.getOutgoingFlows().clear();
                    //建立新方向
                    List<SequenceFlow> newSequenceFlowList = new ArrayList<>();
                    SequenceFlow newSequenceFlow = new SequenceFlow();
                    newSequenceFlow.setId("newSequenceFlowId");
                    newSequenceFlow.setSourceFlowElement(curFlowNode);
                    newSequenceFlow.setTargetFlowElement(lastFlowNode);
                    newSequenceFlowList.add(newSequenceFlow);
                    curFlowNode.setOutgoingFlows(newSequenceFlowList);
                    // 完成任务
                    taskService.complete(task.getId());
                    //恢复原方向
                    curFlowNode.setOutgoingFlows(oriSequenceFlows);
//                    org.activiti.engine.task.Task nextTask = taskService
//                            .createTaskQuery().processInstanceId(processInstanceId).singleResult();
//                    // 设置执行人
//                    if(nextTask!=null) {
//                        taskService.(nextTask.getId(), lastTask.getAssignee());
//                    }
                    return "驳回成功";
                }
            }
        }
        return "审批失败";
    }

    public String adminTask(String usernameFromToken, String taskId,String isAgree) {
        Page<Task> page = taskRuntime.tasks(Pageable.of(0, 10), new GetTasksPayloadBuilder().withGroup("admin").build());
        if (page.getTotalItems()<=0){
            return "无需要审批的任务";
        }
        for (Task task : page.getContent()) {
            if (task.getId().equals(taskId)){
                //拾取任务
//                taskRuntime.release(new ReleaseTaskPayloadBuilder().withTaskId(taskId).build());
                taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(taskId).build());
                if (isAgree.equals("yes")){

                    //完成任务
                    taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskId).withVariable("isAgree",isAgree).build());
                    return "审批成功";
                }else{
                    //驳回操作

                    //获取任务
                    String processInstanceId = task.getProcessInstanceId();

                    HistoryService historyService = processEngine.getHistoryService();
                    RepositoryService repositoryService = processEngine.getRepositoryService();
                    RuntimeService runtimeService = processEngine.getRuntimeService();
                    TaskService taskService = processEngine.getTaskService();
                    // 取得所有历史任务按时间降序排序
                    List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
                            .processInstanceId(processInstanceId)
                            .orderByTaskCreateTime()
                            .desc()
                            .list();
                    if (ObjectUtils.isEmpty(htiList) || htiList.size() < 2) {
                        return "驳回失败,";
                    }
                    // list里的第二条代表上一个任务
                    HistoricTaskInstance lastTask = htiList.get(1);
                    // list里第二条代表当前任务
                    HistoricTaskInstance curTask = htiList.get(0);
                    // 当前节点的executionId
                    String curExecutionId = curTask.getExecutionId();
                    // 上个节点的taskId
                    String lastTaskId = lastTask.getId();
                    // 上个节点的executionId
                    String lastExecutionId = lastTask.getExecutionId();
                    if (null == lastTaskId) {
                        throw new RuntimeException("LAST TASK IS NULL");
                    }
                    String processDefinitionId = lastTask.getProcessDefinitionId();
                    BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
                    String lastActivityId = null;
                    List<HistoricActivityInstance> haiFinishedList = historyService.createHistoricActivityInstanceQuery()
                            .executionId(lastExecutionId).finished().list();
                    for (HistoricActivityInstance hai : haiFinishedList) {
                        if (lastTaskId.equals(hai.getTaskId())) {
                            // 得到ActivityId，只有HistoricActivityInstance对象里才有此方法
                            lastActivityId = hai.getActivityId();
                            break;
                        }
                    }
                    // 得到上个节点的信息
                    FlowNode lastFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(lastActivityId);
                    // 取得当前节点的信息
                    Execution execution = runtimeService.createExecutionQuery().executionId(curExecutionId).singleResult();
                    String curActivityId = execution.getActivityId();
                    FlowNode curFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(curActivityId);
                    //记录当前节点的原活动方向
                    List<SequenceFlow> oriSequenceFlows = new ArrayList<>();
                    oriSequenceFlows.addAll(curFlowNode.getOutgoingFlows());
                    //清理活动方向
                    curFlowNode.getOutgoingFlows().clear();
                    //建立新方向
                    List<SequenceFlow> newSequenceFlowList = new ArrayList<>();
                    SequenceFlow newSequenceFlow = new SequenceFlow();
                    newSequenceFlow.setId("newSequenceFlowId");
                    newSequenceFlow.setSourceFlowElement(curFlowNode);
                    newSequenceFlow.setTargetFlowElement(lastFlowNode);
                    newSequenceFlowList.add(newSequenceFlow);
                    curFlowNode.setOutgoingFlows(newSequenceFlowList);
                    // 完成任务
                    taskService.complete(task.getId());
                    //恢复原方向
                    curFlowNode.setOutgoingFlows(oriSequenceFlows);
//                    org.activiti.engine.task.Task nextTask = taskService
//                            .createTaskQuery().processInstanceId(processInstanceId).singleResult();
//                    // 设置执行人
//                    if(nextTask!=null) {
//                        taskService.(nextTask.getId(), lastTask.getAssignee());
//                    }
                    return "驳回成功";
                }
            }
        }
        return "审批失败";
    }

    public List<HistoricActivityInstance> queryInstanceHistory(String instanceId) {
        List<HistoricActivityInstance> list = processEngine.getHistoryService().createHistoricActivityInstanceQuery().processInstanceId(instanceId).orderByHistoricActivityInstanceStartTime().desc().list();
        return list;
    }

    public Page<Task> queryTask(String usernameFromToken) {
        Page<Task> page = taskRuntime.tasks(Pageable.of(0, 10));
        for (Task task : page.getContent()) {
            List<VariableInstance> variables = taskRuntime.variables(new GetTaskVariablesPayloadBuilder().withTaskId(task.getId()).build());

        }
        return page;
    }

    public Map<String,Object> getTaskData(String taskId) {
        List<VariableInstance> variables = taskRuntime.variables(new GetTaskVariablesPayloadBuilder().withTaskId(taskId).build());
        Map<String,Object> map=new HashMap<>();
        for (VariableInstance variable : variables) {
            map.put(variable.getName(),variable.getValue());
        }
        return map;
    }

    public String userApplyTask(String usernameFromToken, Map<String, String> map) {
        System.out.println("用户提交修改申请");

        Map<String,Object> paramMap=new HashMap<>();
        paramMap.put("day",map.get("day"));
        paramMap.put("cause",map.get("cause"));
        taskRuntime.setVariables(new SetTaskVariablesPayloadBuilder().withVariables(paramMap).withTaskId(map.get("taskId")).build());

//        taskRuntime.release(new ReleaseTaskPayloadBuilder().withTaskId(map.get("taskId")).build());

        //拾取任务
        taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(map.get("taskId")).build());
        //完成任务
        taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(map.get("taskId")).build());
        return "递交成功";
    }
}
